/****************************************************************************
*
* Copyright (c) 2023  C*Core -   All Rights Reserved
*
* THIS SOFTWARE IS DISTRIBUTED "AS IS, " AND ALL WARRANTIES ARE DISCLAIMED,
* INCLUDING MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* PROJECT     : CCF2011BC
* DESCRIPTION : console driver interface
* HISTORY     : Initial version.
* @file     spi_demo.c
* @version  1.1
* @date     2023 - 02 - 20
* @brief    Initial version.
*
*****************************************************************************/
#include "spi_lld.h"
#include "sys.h"
#include "console.h"
#include "common.h"
#include "led_hw.h"
#include "spi_demo.h"

#define SPI_CASE1 0
#define SPI_CASE2 0
#define SPI_CASE3 0
#define SPI_CASE4 0
#define SPI_CASE5 0
#define SPI_CASE6 1
#define SPI_CASE7 0

#define  CCORE_EVB  1
/* ==  ==  ==  ==  ==  ==  ==  ==  ==  = ==  ==  ==  ==  ==  ==  ==  ==  ==  */
/* Driver exported variables.                                                */
/* ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  ==  = */
/*
 * SPI TX and RX buffers.
 */
static uint8_t txbuf[1024];
static uint8_t rxbuf[1024];
static uint8_t rxbuf1[1024];

struct CTAR_var
{
    vuint8_t dbr;       //  Double baud Rate  decide the duty cycle
    vuint8_t fmsz;      //  selects the number of bits transferred per frame
    vuint8_t cpol;      //  Clock Polarity
    vuint8_t cpha;      //  Clock Phase
    vuint8_t lsbfe;     //  LSB First
    vuint8_t pcssck;    //  PCS to SCK delay Prescaler
    vuint8_t pasc;      //  After SCK delay Prescaler
    vuint8_t pdt;       //  Dealy after Transfer Prescaler
    vuint8_t pbr;       //  Baud Rate Prescaler
    vuint8_t cssck;     //  PCS to SCK Delay Scaler  t_csc = 1/f_sys * PCSSCK * CSSCK
    vuint8_t asc;       //  After SCK Delay Scaler  t_asc = 1/f_sys * PASC * ASC
    vuint8_t dt;        //  Dealy after Transfer Scaler, t_dt = 1/f_sys * PDT* DT
    vuint8_t br;        //  Baud Rate Scaler SCK baud rate = f_sys*(1 + DBR)/PBR/BR
};
static struct CTAR_var ctar;

/* Spi master configurattion for DSPI0, for SPID1 */
static spi_config_t dspi0_config = {
    DSPI0,                              /*! < Select which DSPI controller is used */
    2000000,                            /*! < Baud rate in bits per second*/
    SPI_INACTIVE_HIGH,                  /*! < PCS polarity in inactive state for all available PCS */
    8,                                  /*! < Number of bits/frame, minimum is 4 - bits , maximum = 16 - bits*/
    SPI_CLOCK_PHASE_2ND_EDGE,           /*! < Selects which phase of clock to capture data */
    SPI_ACTIVE_LOW,                     /*! < Selects clock polarity */
    FALSE,                              /*! < Enable/disable continuous clock */
    FALSE,                              /*! < Option to transmit LSB first */
    SPI_USING_INTERRUPTS,               /*! < Type of DSPI transfer */
    DSPI_DMA_NONE,                      /*! < Type of handing DSPI TX/RX data */
    NULL,                               /*! < User callback function.*/
    TRUE,                               /*! < Enable/disable continuous CS */   /* when using polling */
    0,                                  /*! < Select which CS(PCSIS0~PCSIS5) is used */
};
/* Spi master configurattion for DSPI1, for SPID2 */
static spi_config_t dspi1_config = {
    DSPI1,                                  /*! < Select which DSPI controller is used */
    8000000,                                /*! < Baud rate in bits per second*/
    SPI_INACTIVE_HIGH,                      /*! < PCS polarity in inactive state for all available PCS */
    8,                                      /*! < Number of bits/frame, minimum is 4 - bits , maximum = 16 - bits*/
    SPI_CLOCK_PHASE_2ND_EDGE,               /*! < Selects which phase of clock to capture data */
    SPI_ACTIVE_LOW,                         /*! < Selects clock polarity */
    FALSE,                                  /*! < Enable/disable continuous clock */
    FALSE,                                  /*! < Option to transmit LSB first */
    SPI_USING_INTERRUPTS,                   /*! < Type of DSPI transfer */
    DSPI_DMA_NONE,                          /*! < Type of handing DSPI TX/RX data */
    NULL,                                   /*! < User callback function.*/
    TRUE,                                   /*! < Enable/disable continuous CS */ /* when using polling */
    0,                                      /*! < Select which CS(PCSIS0~PCSIS5) is used */
};
/* Spi master configurattion for DSPI2, for SPID3 */
static spi_config_t dspi2_config = {
    DSPI2,                                  /*! < Select which DSPI controller is used */
    8000000,                              /*! < Baud rate in bits per second*/
    SPI_INACTIVE_LOW,                       /*! < PCS polarity in inactive state for all available PCS */
    8,                                      /*! < Number of bits/frame, minimum is 4 - bits , maximum = 16 - bits*/
    SPI_CLOCK_PHASE_2ND_EDGE,               /*! < Selects which phase of clock to capture data */
    SPI_ACTIVE_HIGH,                        /*! < Selects clock polarity */
    FALSE,                                  /*! < Enable/disable continuous clock */
    FALSE,                                  /*! < Option to transmit LSB first */
    SPI_USING_INTERRUPTS,                   /*! < Type of DSPI transfer */
    DSPI_DMA_RX_AND_TX,                     /*! < Type of handing DSPI TX/RX data */
    NULL,                                   /*! < User callback function.*/
    TRUE,                                   /*! < Enable/disable continuous CS */  /* when using polling */
    0,                                      /*! < Select which CS(PCSIS0~PCSIS5) is used */
};

/* Spi master configurattion for DSPI3, for SPID4 */
static spi_config_t dspi3_config = {
    DSPI3,                                  /*! < Select which DSPI controller is used */
    8000000,                               /*! < Baud rate in bits per second*/
    SPI_INACTIVE_HIGH,                      /*! < PCS polarity in inactive state for all available PCS */
    8,                                      /*! < Number of bits/frame, minimum is 4 - bits , maximum = 16 - bits*/
    SPI_CLOCK_PHASE_2ND_EDGE,               /*! < Selects which phase of clock to capture data */
    SPI_ACTIVE_LOW,                         /*! < Selects clock polarity */
    FALSE,                                  /*! < Enable/disable continuous clock */
    FALSE,                                  /*! < Option to transmit LSB first */
    SPI_USING_INTERRUPTS,                   /*! < Type of DSPI transfer */
    DSPI_DMA_RX_ONLY,                       /*! < Type of handing DSPI TX/RX data */
    NULL,                                   /*! < User callback function.*/
    TRUE,                                   /*! < Enable/disable continuous CS */  /* when using polling */
    0,                                      /*! < Select which CS(PCSIS0~PCSIS5) is used */
};

/* Spi master configurattion for DSPI4, for SPID5 */
static spi_config_t dspi4_config = {
    DSPI4,                                  /*! < Select which DSPI controller is used */
    8000000,                               /*! < Baud rate in bits per second*/
    SPI_INACTIVE_HIGH,                      /*! < PCS polarity in inactive state for all available PCS */
    8,                                      /*! < Number of bits/frame, minimum is 4 - bits , maximum = 16 - bits*/
    SPI_CLOCK_PHASE_2ND_EDGE,               /*! < Selects which phase of clock to capture data */
    SPI_ACTIVE_LOW,                         /*! < Selects clock polarity */
    FALSE,                                  /*! < Enable/disable continuous clock */
    FALSE,                                  /*! < Option to transmit LSB first */
    SPI_USING_INTERRUPTS,                   /*! < Type of DSPI transfer */
    DSPI_DMA_NONE,                          /*! < Type of handing DSPI TX/RX data */
    NULL,                                   /*! < User callback function.*/
    TRUE,                                   /*! < Enable/disable continuous CS */   /* when using polling */
    0,                                      /*! < Select which CS(PCSIS0~PCSIS5) is used */
};

/*******************************************************************************
 * @brief     SPI_DEMO_Configure
 * @param[in] uint8_t DSPIx, spi_transfer_type_t transferType, spi_dma_type_t dmaType,
 *          uint8_t continuousPCS, uint32_t baudrate
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void SPI_DEMO_Configure(uint8_t DSPIx, spi_transfer_type_t transferType, spi_dma_type_t dmaType,
        uint8_t continuousPCS, uint32_t baudrate)
{
    uint32_t i = 0u;
    spi_config_t* const dspi_configs[5] = {&dspi0_config, &dspi1_config, &dspi2_config, \
            &dspi3_config, &dspi4_config};

    if (DSPIx < 5u)
    {
        dspi_configs[DSPIx]->dmaType = dmaType;
        dspi_configs[DSPIx]->transferType = transferType;
        dspi_configs[DSPIx]->continuousPCS = continuousPCS;
        dspi_configs[DSPIx]->bitsPerSec = baudrate;
    }
    else
    {
        for (i = 0u; i < 5u; i++)
        {
            dspi_configs[i]->dmaType = dmaType;
            dspi_configs[i]->transferType = transferType;
            dspi_configs[i]->continuousPCS = continuousPCS;
            dspi_configs[i]->bitsPerSec = baudrate;
        }
    }
}
/*******************************************************************************
 * @brief     SPI_Demo_Variable_Init
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void SPI_Demo_Variable_Init(void)
{
    uint16_t i;

    /* Prepare transmit pattern.*/
    for (i = 0u; i < sizeof(txbuf); i++)
    {
        txbuf[i] = (uint8_t)(i + 1u);
    }
    cc_memset(rxbuf, 0, sizeof(rxbuf));
    cc_memset(rxbuf1, 0, sizeof(rxbuf1));
}
/*******************************************************************************
 * @brief    SPI_DEMO_INT_DMA_Exchange_Loopback_Test
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void SPI_DEMO_INT_DMA_Exchange_Loopback_Test(void)
{
    uint32_t ret = 0u;

    SPI_LLD_Exchange_DMA(&SPID1, 16, txbuf, rxbuf);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID1); /*PRQA S 1823*/
    ret = check_memcpy(txbuf, rxbuf, 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK DMA TEST: DSPI0 not success!\n");
    }
    SPI_LLD_Exchange_DMA(&SPID2, 16, &txbuf[16], &rxbuf[16]);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID2); /*PRQA S 1823*/
    ret = check_memcpy(&txbuf[16U], &rxbuf[16U], 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK DMA TEST: DSPI1 not success!\n");
    }
#if defined(CCFC2011BC_40L3_LQFP100) || defined(CCFC2011BC_40L5_LQFP144)
    SPI_LLD_Exchange_DMA(&SPID3, 16, &txbuf[32], &rxbuf[32]);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID3); /*PRQA S 1823*/
    ret = check_memcpy(&txbuf[32U], &rxbuf[32U], 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK DMA TEST: DSPI2 not success!\n");
    }
#if defined CCFC2011BC_40L5_LQFP144
    SPI_LLD_Exchange_DMA(&SPID4, 16, &txbuf[48], &rxbuf[48]);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID4); /*PRQA S 1823*/
    ret = check_memcpy(&txbuf[48U], &rxbuf[48U], 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK DMA TEST: DSPI3 not success!\n");
    }
    SPI_LLD_Exchange_DMA(&SPID5, 16, &txbuf[64], &rxbuf[64]);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID5); /*PRQA S 1823*/
    ret = check_memcpy(&txbuf[64U], &rxbuf[64U], 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK DMA TEST: DSPI4 not success!\n");
    }

#endif	
#endif
}
/*******************************************************************************
 * @brief    SPI_DEMO_INT_Exchange_Loopback_Test
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void SPI_DEMO_INT_Exchange_Loopback_Test(void)
{
    uint32_t ret;

    SPI_LLD_Exchange(&SPID1, 16, txbuf, rxbuf);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID1); /*PRQA S 1823*/
    ret = check_memcpy(txbuf, rxbuf, 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK INT TEST: DSPI0 not success!\n");
    }
    SPI_LLD_Exchange(&SPID2, 16, &txbuf[16], &rxbuf[16]);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID2); /*PRQA S 1823*/
    ret = check_memcpy(&txbuf[16U], &rxbuf[16U], 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK INT TEST: DSPI1 not success!\n");
    }
#if defined(CCFC2011BC_40L3_LQFP100) || defined(CCFC2011BC_40L5_LQFP144)
    SPI_LLD_Exchange(&SPID3, 16, &txbuf[32], &rxbuf[32]);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID3); /*PRQA S 1823*/
    ret = check_memcpy(&txbuf[32U], &rxbuf[32U], 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK INT TEST: DSPI2 not success!\n");
    }
#if defined CCFC2011BC_40L5_LQFP144
    SPI_LLD_Exchange(&SPID4, 16, &txbuf[48], &rxbuf[48]);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID4); /*PRQA S 1823*/
    ret = check_memcpy(&txbuf[48U], &rxbuf[48U], 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK INT TEST: DSPI3 not success!\n");
    }
    SPI_LLD_Exchange(&SPID5, 16, &txbuf[64], &rxbuf[64]);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID5); /*PRQA S 1823*/
    ret = check_memcpy(&txbuf[64U], &rxbuf[64U], 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK INT TEST: DSPI4 not success!\n");
    }
#endif
#endif
}
/*******************************************************************************
 * @brief   SPI_DEMO_Polled_Exchange_Loopback_Test
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void SPI_DEMO_Polled_Exchange_Loopback_Test(void)
{
    uint32_t ret;

    SPI_LLD_Polled_Exchange(&SPID1, 16, txbuf, rxbuf);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID1); /*PRQA S 1823*/
    ret = check_memcpy(txbuf, rxbuf, 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK Poll TEST: DSPI0 not success!\n");
    }
    SPI_LLD_Polled_Exchange(&SPID2, 16, &txbuf[16], &rxbuf[16]);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID2); /*PRQA S 1823*/
    ret = check_memcpy(&txbuf[16U], &rxbuf[16U], 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK Poll TEST: DSPI1 not success!\n");
    }
#if defined(CCFC2011BC_40L3_LQFP100) || defined(CCFC2011BC_40L5_LQFP144) 
    SPI_LLD_Polled_Exchange(&SPID3, 16, &txbuf[32], &rxbuf[32]);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID3); /*PRQA S 1823*/
    ret = check_memcpy(&txbuf[32U], &rxbuf[32U], 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK Poll TEST: DSPI2 not success!\n");
    }
#if defined CCFC2011BC_40L5_LQFP144
    SPI_LLD_Polled_Exchange(&SPID4, 16, &txbuf[48], &rxbuf[48]);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID4); /*PRQA S 1823*/
    ret = check_memcpy(&txbuf[48U], &rxbuf[48U], 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK Poll TEST: DSPI3 not success!\n");
    }
    SPI_LLD_Polled_Exchange(&SPID5, 16, &txbuf[64], &rxbuf[64]);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID5); /*PRQA S 1823*/
    ret = check_memcpy(&txbuf[64U], &rxbuf[64U], 16U);
    if (ret == 0u)
    {
        PSPRINTF("\n LOOPBACK Poll TEST: DSPI4 not success!\n");
    }

#endif
#endif
}
/*******************************************************************************
 * @brief    SPI_DEMO_LOOBACK_INT_TEST,can be used to test the 
 *           function of all DSPI controllers in EVB is normal or not.
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void SPI_DEMO_LOOBACK_INT_TEST(void)
{
    /*initialize variable in the SPI Demo */
    SPI_Demo_Variable_Init();

    SPI_DEMO_Configure(6, SPI_USING_INTERRUPTS, DSPI_DMA_NONE, TRUE, 8000000);
    /*SPI Mater Init */
    SPI_LLD_Init(&SPID1, &dspi0_config, SPI_MASTER);
    SPI_LLD_Init(&SPID2, &dspi1_config, SPI_MASTER);
#if defined(CCFC2011BC_40L3_LQFP100) || defined(CCFC2011BC_40L5_LQFP144) 
    SPI_LLD_Init(&SPID3, &dspi2_config, SPI_MASTER);
#if defined CCFC2011BC_40L5_LQFP144
    SPI_LLD_Init(&SPID4, &dspi3_config, SPI_MASTER);
    SPI_LLD_Init(&SPID5, &dspi4_config, SPI_MASTER); 
#endif
#endif
    /*user switch differnt test case from spi_demo.c*/
    SPI_DEMO_INT_Exchange_Loopback_Test();

    PSPRINTF("\n LOOPBACK TEST using INTTERRUPT:success!\n");
}

/*******************************************************************************
 * @brief    SPI_DEMO_LOOBACK_INT_DMA_TEST,can be used to test the 
 *           function of all DSPI controllers in EVB is normal or not.
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void SPI_DEMO_LOOBACK_INT_DMA_TEST(void)
{
    /*initialize variable in the SPI Demo */
    SPI_Demo_Variable_Init();

    SPI_DEMO_Configure(6, SPI_USING_INTERRUPTS, DSPI_DMA_RX_AND_TX, TRUE, 4000000);
    /*SPI Mater Init */
    SPI_LLD_Init(&SPID1, &dspi0_config, SPI_MASTER);
    SPI_LLD_Init(&SPID2, &dspi1_config, SPI_MASTER);
#if defined(CCFC2011BC_40L3_LQFP100) || defined(CCFC2011BC_40L5_LQFP144)
    SPI_LLD_Init(&SPID3, &dspi2_config, SPI_MASTER);
#if defined CCFC2011BC_40L5_LQFP144
    SPI_LLD_Init(&SPID4, &dspi3_config, SPI_MASTER);
    SPI_LLD_Init(&SPID5, &dspi4_config, SPI_MASTER);
#endif
#endif
    /*user switch differnt test case from spi_demo.c*/
    SPI_DEMO_INT_DMA_Exchange_Loopback_Test();

    PSPRINTF("\n LOOPBACK TEST using DMA:success!\n");
}

/*******************************************************************************
 * @brief    SPI_DEMO_LOOBACK_POOLLING_TEST,can be used to test the 
 *           function of all DSPI controllers in EVB is normal or not.
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void SPI_DEMO_LOOBACK_POOLLING_TEST(void)
{
    /*initialize variable in the SPI Demo */
    SPI_Demo_Variable_Init();

    SPI_DEMO_Configure(6, SPI_USING_POLLING, DSPI_DMA_NONE, TRUE, 16000000);

    /*SPI Mater Init */
    SPI_LLD_Init(&SPID1, &dspi0_config, SPI_MASTER);
    SPI_LLD_Init(&SPID2, &dspi1_config, SPI_MASTER);
#if defined(CCFC2011BC_40L3_LQFP100) || defined(CCFC2011BC_40L5_LQFP144)
    SPI_LLD_Init(&SPID3, &dspi2_config, SPI_MASTER);
#if defined CCFC2011BC_40L5_LQFP144
    SPI_LLD_Init(&SPID4, &dspi3_config, SPI_MASTER);
    SPI_LLD_Init(&SPID5, &dspi4_config, SPI_MASTER);
#endif
#endif
    /*user switch differnt test case from spi_demo.c*/
    SPI_DEMO_Polled_Exchange_Loopback_Test();

    PSPRINTF("\n LOOPBACK TEST using POLLING :success!\n");
}

static void SPI_SEND_Receive_INT(void)
{
    SPI_LLD_Slave_Receive(&SPID2, 8, rxbuf);
    SPI_LLD_Send(&SPID1, 8, txbuf);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID2);    /*PRQA S 1823*/
}

/*******************************************************************************
 * @brief   ctar_init
 * @param[in]  uint32_t* ctar_reg
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void ctar_init(uint32_t* ctar_reg)
{
    *ctar_reg = 0u;
    *ctar_reg |= ((uint32_t)ctar.dbr << 31u);
    *ctar_reg |= ((uint32_t)ctar.cpol << 26u);
    *ctar_reg |= ((uint32_t)ctar.cpha << 25u);
    *ctar_reg |= ((uint32_t)ctar.lsbfe << 23u);
    *ctar_reg |= ((uint32_t)ctar.pcssck << 22u);
    *ctar_reg |= ((uint32_t)ctar.pasc << 20u);
    *ctar_reg |= ((uint32_t)ctar.pdt << 18u);
    *ctar_reg |= ((uint32_t)ctar.pbr << 16u);
    *ctar_reg |= ((uint32_t)ctar.cssck << 12u);
    *ctar_reg |= ((uint32_t)ctar.asc << 8u);
    *ctar_reg |= ((uint32_t)ctar.dt << 4u);
    *ctar_reg |= (uint32_t)ctar.br ;
}
/*******************************************************************************
 * @brief   SPI_Update_CATR0
 * @param[in]  (*testcase)(void)
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
static uint8_t SPI_Update_CATR0(void (*testcase)(void))
{
    uint8_t ret = 0u;
    uint32_t ctar_reg = 0u, count = 0u;
    for (ctar.dbr = 0u; ctar.dbr < 2u; ctar.dbr++) /*PRQA S 3387,2461*/
    {
        for (ctar.cpol = 0u; ctar.cpol < 2u; ctar.cpol++)/*PRQA S 3387,2461*/
        {
            for (ctar.cpha = 0u; ctar.cpha < 2u; ctar.cpha++)/*PRQA S 3387,2461*/
            {
                for (ctar.lsbfe = 0u; ctar.lsbfe < 2u; ctar.lsbfe++)/*PRQA S 3387,2461*/
                {
                    for (ctar.pcssck = 0u; ctar.pcssck < 4u; ctar.pcssck++)/*PRQA S 3387,2461*/
                    {
                        for (ctar.pasc = 0u; ctar.pasc < 4u; ctar.pasc++)/*PRQA S 3387,2461*/
                        {
                            for (ctar.pdt = 0u; ctar.pdt < 4u; ctar.pdt++)/*PRQA S 3387,2461*/
                            {
                                for (ctar.pbr = 0u; ctar.pbr < 4u; ctar.pbr++)/*PRQA S 3387,2461*/
                                {
                                    for (ctar.cssck = 0u; ctar.cssck < 16u; ctar.cssck = ctar.cssck + 2u)/*PRQA S 2461*/
                                    {
                                        for (ctar.asc = 0u; ctar.asc < 16u; ctar.asc = ctar.asc + 2u)/*PRQA S 2461*/
                                        {
                                            for (ctar.dt = 0u; ctar.dt < 16u; ctar.dt = ctar.dt + 2u)/*PRQA S 2461*/
                                            {
                                                for (ctar.br = 0u; ctar.br < 16u; ctar.br = ctar.br + 2u) /*PRQA S 2461*/
                                                {
                                                    ctar_init(&ctar_reg);
                                                    SPI_LLD_SetCATR0_NoFmsz(&SPID1, ctar_reg);
                                                    SPI_LLD_SetCATR0_NoFmsz(&SPID2, ctar_reg);

                                                    /*switch different case in here */
                                                    (*testcase)();

                                                    if (check_memcpy(rxbuf, txbuf, 8u) == 0u)
                                                    {
                                                        while (1)
                                                        {}
                                                    }
                                                    count++;
                                                    PSPRINTF("dbr = %d, cpol = %d, cpha = %d", ctar.dbr, ctar.cpol,ctar.cpha);/*PRQA S 0404,1029*/
                                                    PSPRINTF("lsbfe = %d, pcssck = %d, pasc = %d,", ctar.lsbfe, ctar.pcssck, ctar.pasc);/*PRQA S 0404,1029*/
                                                    PSPRINTF(" pdt = %d, pbr = %d, count = %d \n", ctar.pdt, ctar.pbr, count);/*PRQA S 0404,1029*/
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    ret = 1;
    return ret;
}
/*******************************************************************************
 * @brief   SPI_Test_Case1
 * @param[in]  None
 * @retval     None
 *      SOUT        SIN
 * DSPI0: PA13 < -->PA12
 * DSPI1: PC5  < -->PC4
 * DSPI2: PC13 < -->PC12
 * DSPI3: PG2  < -->PG5
 * DSPI4: PG12 < -->PG10
 * @notapi
 *******************************************************************************/
static void SPI_Test_Case1(void) /* PRQA S 3219 */
{
    SPI_DEMO_LOOBACK_POOLLING_TEST();
    SPI_DEMO_LOOBACK_INT_TEST();
    SPI_DEMO_LOOBACK_INT_DMA_TEST();
}

/*******************************************************************************
 * @brief   SPI_Test_Case2
 * @param[in]  None
 * @retval     None
 * @connection SPI Master                                    SPI Slave
 * SPI_DEMO_INT_EXCHANE_MASTER_TEST < -------->SPI_DEMO_INT_EXCHANE_SLAVE_TEST
 * CONNECTION:2023
 * SPID1                                             SPID2
 * DSPI0                                             DSPI1
 * SOUT:          PA[12]            < --------->     PC[5]       SIN
 * SIN:            PA[13]            < --------->    PC[4]       SOUT
 * SCK:           PA[14]            < --------->     PC[2]       SCK
 * CS0_0:         PA[15]            < --------->     PC[3]       CS0_0
 * @notapi
 *******************************************************************************/
static void SPI_Test_Case2(void) /* PRQA S 3219 */
{
    /* Set the current priority */
    INTC_CPR_Init((uint8_t)CPR_PRI_0);
    /*initialize variable in the SPI Demo */
    SPI_Demo_Variable_Init();

    SPI_DEMO_Configure(0, SPI_USING_INTERRUPTS, DSPI_DMA_NONE, TRUE, 4000000);
    SPI_DEMO_Configure(1, SPI_USING_INTERRUPTS, DSPI_DMA_NONE, TRUE, 4000000);

    SPI_LLD_Init(&SPID1, &dspi0_config, SPI_MASTER);
    SPI_LLD_Init(&SPID2, &dspi1_config, SPI_SLAVE);

    while (SPI_Update_CATR0(&SPI_SEND_Receive_INT) != 1u)
     {};

    PSPRINTF("spi_different_CTAR_configure_INT_test  is succeed! \n");
}

/*******************************************************************************
 * @brief   SPI_TEST_Case3,SPI_DEMO_INT_SEND_RECEIVE_TEST
 * @param[in]  None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void SPI_TEST_Case3(void) /* PRQA S 3219 */
{
    /* Set the current priority */
    INTC_CPR_Init((uint8_t)CPR_PRI_0);

    /*initialize variable in the SPI Demo */
    SPI_Demo_Variable_Init();

    SPI_LLD_Init(&SPID1, &dspi0_config, SPI_MASTER);
    SPI_LLD_Init(&SPID2, &dspi1_config, SPI_SLAVE);

    SPI_LLD_Slave_Receive(&SPID2, 8, rxbuf);
    SPI_LLD_Send(&SPID1, 8, txbuf);
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID2); /*PRQA S 1823*/

    if ((uint8_t)check_memcpy(rxbuf, txbuf, 8) == 0u)
    {
        while (1)
        {}
    }
    PSPRINTF("SPI_DEMO_INT_SEND_RECEIVE_TEST  is succeed \n");
}

/*******************************************************************************
 * @brief   SPI_TEST_Case4,SPI_DEMO_INT_SEND_RECEIVE_TEST
 * @param[in]  None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void SPI_TEST_Case4(void) /* PRQA S 3219 */
{
    /* Set the current priority */
    INTC_CPR_Init((uint8_t)CPR_PRI_0);

    /*initialize variable in the SPI Demo */
    SPI_Demo_Variable_Init();

    SPI_LLD_Init(&SPID1, &dspi0_config, SPI_MASTER);
    SPI_LLD_Init(&SPID2, &dspi1_config, SPI_SLAVE);

    SPI_LLD_Slave_Receive(&SPID2, 8, rxbuf);
    SPI_LLD_Exchange(&SPID1, 8, txbuf, rxbuf1);

    while ((SPID1.ready == 1u) || (SPID2.ready == 1u))
    {}

    if ((uint8_t)check_memcpy(rxbuf, txbuf, 8) == 0u)
    {
        while (1)
        {}
    }
    PSPRINTF("SPI_DEMO_INT_EXCHANE_RECEIVE_TEST  is succeed \n");
}

/*******************************************************************************
 * @brief      SPI_TEST_Case5,SPI_DEMO_INT_SEND_RECEIVE_TEST
 * @param[in]  None
 * @retval     None
 * @notapi
 *******************************************************************************/
static void SPI_TEST_Case5(void) /* PRQA S 3219 */
{
    /* Set the current priority */
    INTC_CPR_Init((uint8_t)CPR_PRI_0);

    /*initialize variable in the SPI Demo */
    SPI_Demo_Variable_Init();

    SPI_LLD_Init(&SPID1, &dspi0_config, SPI_MASTER);
    SPI_LLD_Init(&SPID2, &dspi1_config, SPI_SLAVE);

	SPI_LLD_Send(&SPID2, 8, txbuf);
    SPI_LLD_Master_Receive(&SPID1, 8, rxbuf);

    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID1); /*PRQA S 1823*/
    SPI_WAIT_FOR_TXRX_COMPLETION(&SPID2); /*PRQA S 1823*/

    if ((uint8_t)check_memcpy(rxbuf, txbuf, 8) == 0u)
    {
        while (1)
        {}
    }
    PSPRINTF("SPI_DEMO_INT_RECIEVE_SEND_TEST  is succeed \n");
}

/*
 * @brief   SPI_TEST_Case5,SPI_DEMO_INT_SEND_RECEIVE_TEST
 * @param[in]  None
 * @retval     None
 * @notapi
 *            SPI Master                                                SPI Slave
 * SPI_DEMO_INT_EXCHANE_MASTER_TEST             < -------->        SPI_DEMO_INT_EXCHANE_SLAVE_TEST
 * CONNECTION:
 * SIN:          PA[12]                        < --------->        PA[13]       SOUT
 * SOUT:         PA[13]                        < --------->        PA[12]       SIN
 * SCK:          PA[14]                        < --------->        PA[14]       SCK
 * CS0_0:        PA[15]                        < --------->        PA[15]       CS0_0
 * user switch differnt test case in here:
 * INT:
 * SPI_DEMO_INT_Exchange_Test                   < --------->     SPI_DEMO_INT_Exchange_Test
 * SPI_DEMO_INT_Exchange_Test                   < --------->     SPI_DEMO_INT_Send_Test
 * SPI_DEMO_INT_Exchange_Test                   < --------->     SPI_DEMO_Slave_INT_ReceiveNbyte_Test
 * SPI_DEMO_INT_Send_Test                       < --------->     SPI_DEMO_INT_Exchange_Test
 * SPI_DEMO_INT_Send_Test                       < --------->     SPI_DEMO_Slave_INT_ReceiveNbyte_Test
 * SPI_DEMO_Master_INT_ReceiveNbyte_Test        < --------->     SPI_DEMO_INT_Exchange_Test
 * SPI_DEMO_Master_INT_ReceiveNbyte_Test        < --------->     SPI_DEMO_INT_Send_Test
 *
 * INT + DMA:
 * SPI_DEMO_INT_DMA_Exchange_Test               < --------->     SPI_DEMO_INT_DMA_Exchange_Test
 * SPI_DEMO_INT_DMA_Exchange_Test               < --------->     SPI_Demo_INT_DMA_send_Test
 * SPI_DEMO_INT_DMA_Exchange_Test               < --------->     SPI_DEMO_INT_DMA_OnlyRx_Exchange_Test XXX
 * SPI_Demo_INT_DMA_send_Test                   < --------->     SPI_DEMO_INT_DMA_Exchange_Test
 * SPI_Demo_INT_DMA_send_Test                   < --------->     SPI_DEMO_INT_DMA_OnlyRx_Exchange_Test XXX
 * SPI_DEMO_INT_DMA_OnlyRx_Exchange_Test        < --------->     SPI_Demo_INT_DMA_send_Test
 *
 * POLL:
 * SPI_DEMO_Polled_Exchange_Test                < --------->    SPI_DEMO_Polled_Exchange_Test
 * SPI_DEMO_Polled_Exchange_Test                < --------->    SPI_DEMO_Polled_Send_Test
 * SPI_DEMO_Polled_Exchange_Test                < --------->    SPI_DEMO_Slave_Polled_ReceiveNbyte_Test
 * SPI_DEMO_Polled_Send_Test                    < --------->    SPI_DEMO_Slave_Polled_ReceiveNbyte_Test
 * SPI_DEMO_Polled_Send_Test                    < --------->    SPI_DEMO_Polled_Exchange_Test
 *
 * */
/*for MASTER*/
static void SPI_TEST_Case6(void) /* PRQA S 3219 */
{
    //static uint8_t txbuf_test[124] = {255};
    //static uint8_t rxbuf_test[124] = {1};
    //uint8_t i = 0;
    

    /*initialize variable in the Spi Demo */
    SPI_Demo_Variable_Init();
    /*SPI Mater Init */
    SPI_DEMO_Configure(0, SPI_USING_INTERRUPTS, DSPI_DMA_NONE, TRUE, 2000000);
    SPI_LLD_Init(&SPID1, &dspi0_config, SPI_MASTER);
    #if 0
    for (i;i<255;i++)
    {
    	if(i<4)txbuf_test[i] = 0;
    	else txbuf_test[i] = 255;	
    }
    
    for (i=0;i<1 ;i++)
    //for(;;)
    {
        LED_Set(LED1, 1);              /* LED ON.                  */
        /*user switch differnt test case in here*/
        SPI_LLD_Exchange(&SPID1, 124, txbuf_test, rxbuf_test); /* 4字节0起始信号+4字节LED*29个灯+4字节1结束信号 = 124字节 */
        SPI_WAIT_FOR_TXRX_COMPLETION(&SPID1); /*PRQA S 1823*/
        LED_Set(LED1|LED2|LED3, LED_OFF); /* LED OFF.                */
        delayms(5);
    }
    #endif
}

/*******************************************************************************
 * @brief      SPI_TEST_Case7
 * @param[in]  None
 * @retval     None
 * @notapi     for SLAVE
 *******************************************************************************/
static void SPI_TEST_Case7(void) /* PRQA S 3219 */
{
    /*initialize variable in the Spi Demo */
    SPI_Demo_Variable_Init();

    SPI_DEMO_Configure(0, SPI_USING_INTERRUPTS, DSPI_DMA_NONE, TRUE, 4000000);
    /*SPI Mater Init */
    SPI_LLD_Init(&SPID1, &dspi0_config, SPI_SLAVE);

    for (; ;)
    {
        LED_Set(LED1, 1);              /* LED ON.                  */
        /*user switch differnt test case in here*/
        SPI_LLD_Exchange(&SPID1, 64, txbuf,rxbuf);
        SPI_WAIT_FOR_TXRX_COMPLETION(&SPID1); /*PRQA S 1823*/
        LED_Set(LED1|LED2|LED3, LED_OFF); /* LED OFF.                */
        delayms(50);
    }
}

/*******************************************************************************
 * @brief      Spi_Test_Demo
 * @param[in]  None
 * @param[out] None
 * @retval     None
 * @notapi
 *******************************************************************************/
void Spi_Test_Demo(void)
{
    /* Function: different spi controllers in the same EVB , loopback test*/
#if SPI_CASE1
    SPI_Test_Case1();
#endif
    /* Function: different spi controllers in the same EVB , CTARs test*/
#if SPI_CASE2
    SPI_Test_Case2();
#endif
    /* Function: different spi controllers in the same EVB , send /receive/exchange test*/
#if SPI_CASE3
    SPI_TEST_Case3();
#endif
    
    /* Function: different spi controllers in the same EVB , send /receive/exchange test*/
#if SPI_CASE4
    SPI_TEST_Case4();
#endif
    
    /* Function: different spi controllers in the same EVB , send /receive/exchange test*/
#if SPI_CASE5
    SPI_TEST_Case5();
#endif
    /*Function: the same spi controllers(DSPI0) between  different, send /recive/exchange test*/
#if  SPI_CASE6
    SPI_TEST_Case6();
#endif
#if SPI_CASE7
    SPI_TEST_Case7(); /*PRQA S 2880*/
#endif
}
